第一篇的時候,有簡單的介紹glfw
管理的一系列輸入callback,,我只用了KeyCallback
而已,但也只是做了一個簡單的ESC離開功能。在源始碼的資料夾裡,可以看到除了PC電腦的輸入裝置的處理,glfw
還有搖桿的處理
今天會完成幾個常用的鍵盤輸入功能,會用到以下這幾種Callback
輸入功能的方向很簡單,尤其是單純製作最上層遊戲邏輯的部分,就是
按了甚麼按鍵,做甚麼事情;滑鼠移到哪裡,做甚麼事情
所以開了幾個關於「確定這個輸入是按下還是放開」的函式
// [iron_window] check is key pressed
int IsKeyPressed(KeyCode keycode);
// [iron_window] check is key released after pressed
int IsKeyReleased(KeyCode keycode);
// [iron_window] check is mouse button pressed
int IsMouseButtonPressed(MouseButton mouse_button);
// [iron_window] check is mouse button released
int IsMouseButtonReleased(MouseButton mouse_button);
// [iron_window] get mouse cursor position
V2f GetMousePosition();
// [iron_window] get mouse scroll roll
float GetScrollYOffset();
然後在WINDOW
這個結構存取使用者的狀態。關於KeyCode
跟MouseButton
這兩個enum,我在iron_types.h
把glfw
定義的按鍵ID再複製一份到enum裡面,ID的定義可以參考glfw3.h
的363行開始,然後利用這兩個enum定義出兩個這個陣列存在WINDOW
裡,用於紀錄每個按鍵的狀態。
之後再依照glfw
文件上處理callback的方式,完成這些功能了。
正要測試的時候發現到一點,我的KeyReleased
跟MouseButtonReleased
如果沒按下去,就會一直觸發狀態(這不是廢話嗎~),但我想要的是按下之後,放開時要觸發。
於是我的處理方法也很簡單,直接加上一個跟按鍵狀態同大小的陣列,每一個GameLoop都去比較之前是有按過還是沒按過。最後當Game Loop結束的時候,在EndScene
函式裡面更新按鍵的狀態。
// iron_window.EndScene
glfwSwapBuffers(WINDOW.wnd);
// reset input state
// must put before call `glfwPollEvents`
// keyboard
for (int i = 0; i < MAX_KEY_CODE; i++) {
WINDOW.Keyboard.key_previous_state[i] = WINDOW.Keyboard.key_current_state[i];
}
// mouse
for (int i = 0; i < MAX_MOUSE_BUTTON; i++) {
WINDOW.Mouse.mouse_btn_previous_state[i] = WINDOW.Mouse.mouse_btn_current_state[i];
}
WINDOW.Mouse.scroll_offset = 0.0f;
glfwPollEvents();
這樣基本上就大功告成了...